package com.smartfactory.sail.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartfactory.sail.config.BizzException;
import com.smartfactory.sail.entity.*;
import com.smartfactory.sail.mapper.ItemWorkingprocedurePickingMapper;
import com.smartfactory.sail.service.*;
import com.smartfactory.sail.utils.DateUtils;
import com.smartfactory.sail.vo.item.ItemWorkingprocedureResp;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 工序领料记录 服务实现类
 * </p>
 *
 * @author 王巨壁
 * @since 2019-09-25
 */
@Service
public class ItemWorkingprocedurePickingServiceImpl extends ServiceImpl<ItemWorkingprocedurePickingMapper, ItemWorkingprocedurePicking> implements IItemWorkingprocedurePickingService {

    private IItemWorkingprocedureService itemWorkingprocedureService;
    private IUserService iUserService;
    private IDeptService iDeptService;
    private IPlanService iPlanService;
    private IItemService iItemService;

    public ItemWorkingprocedurePickingServiceImpl(IItemWorkingprocedureService itemWorkingprocedureService, IUserService iUserService, IDeptService iDeptService, IPlanService iPlanService, IItemService iItemService) {
        this.itemWorkingprocedureService = itemWorkingprocedureService;
        this.iUserService = iUserService;
        this.iDeptService = iDeptService;
        this.iPlanService = iPlanService;
        this.iItemService = iItemService;
    }

    @Override
    public boolean addPicking(ItemWorkingprocedurePicking picking) throws BizzException {

        Long userId = picking.getUserId();
        Long workingProcedureId = picking.getWorkingProcedureId();
        Integer pickingSize = picking.getPickingSize();
        //判断这个人是不是这个部门的
        User user = iUserService.getById(userId);
        if (user == null) {
            throw new BizzException("员工不存在");
        }
        //查询这个工序属于哪个部门
        ItemWorkingprocedure workingprocedure = itemWorkingprocedureService.getById(workingProcedureId);
        if (user.getDeptId() != workingprocedure.getDept()) {
            throw new BizzException(user.getReallyName() + " 不属于 " + iDeptService.getById(workingprocedure.getDept()).getDeptName() + ",不允许领料!");
        }

        Integer sort = workingprocedure.getSort();
        //第一道工序 . 领取数量 不能大于 今日领料总数
        if (sort == 0) {
            LambdaQueryWrapper<Plan> planQuery = new LambdaQueryWrapper<>();
            planQuery.eq(Plan::getPlanDate, DateUtils.getNowDate());
            planQuery.eq(Plan::getItemId, workingprocedure.getItemId());
            planQuery.eq(Plan::getOrderId, picking.getOrderId());
            Plan one = iPlanService.getOne(planQuery);
            if (one == null) {
                throw new BizzException("今日无排班 不可领料!");
            }
            //报废率
            Integer scrapRate = iItemService.getById(picking.getItemId()).getScrapRate();
            //今日生产数
            double todaySize = one.getWorkHours() * one.getHourlyCapacity() * ((100 + scrapRate) / 100d);
            //获取所有已领料数量
            LambdaQueryWrapper<ItemWorkingprocedurePicking> pickingLambdaQueryWrapper = new LambdaQueryWrapper<>();
            pickingLambdaQueryWrapper.eq(ItemWorkingprocedurePicking::getItemId, picking.getItemId());
            pickingLambdaQueryWrapper.eq(ItemWorkingprocedurePicking::getOrderId, picking.getOrderId());
            pickingLambdaQueryWrapper.eq(ItemWorkingprocedurePicking::getWorkingProcedureId, picking.getWorkingProcedureId());
            int pickedSize = 0;
            for (ItemWorkingprocedurePicking itemWorkingprocedurePicking : list(pickingLambdaQueryWrapper)) {
                pickedSize += itemWorkingprocedurePicking.getPickingSize();
            }

            if (pickedSize + pickingSize > todaySize) {
                throw new BizzException("已领料: " + pickedSize + "; 领料数不能大于今日生产总数!");
            }
        } else {//非第一道工序
            //(非第一次)  本次领取数量 +  历史领取数量  <= 上道工序的完成数量
            LambdaQueryWrapper<ItemWorkingprocedurePicking> pickingQuery = new LambdaQueryWrapper<>();
            pickingQuery.eq(ItemWorkingprocedurePicking::getWorkingProcedureId, workingProcedureId);
            List<ItemWorkingprocedurePicking> list = list();
            int historySize = 0;
            for (ItemWorkingprocedurePicking itemWorkingprocedurePicking : list) {
                historySize += itemWorkingprocedurePicking.getPickingSize();
            }
            //获取上道工序的总完成数量
            LambdaQueryWrapper<ItemWorkingprocedure> workingQuery = new LambdaQueryWrapper<>();
            workingQuery.eq(ItemWorkingprocedure::getDept, workingprocedure.getDept());
            workingQuery.eq(ItemWorkingprocedure::getItemId, workingprocedure.getItemId());
            workingQuery.eq(ItemWorkingprocedure::getSort, sort - 1);
            ItemWorkingprocedure one = itemWorkingprocedureService.getOne(workingQuery);
            List<ItemWorkingprocedureResp> detail = itemWorkingprocedureService.detail(picking.getOrderId(), picking.getItemId(), workingprocedure.getDept());
            for (ItemWorkingprocedureResp itemWorkingprocedureResp : detail) {
                if (itemWorkingprocedureResp.getId() == one.getId() && itemWorkingprocedureResp.getCompletedNumber() < historySize + pickingSize) {
                    throw new BizzException("领料数不能大于上道工序完成总数!");
                }
            }
        }
        return save(picking);
    }

    /**
     * @param itemId             产品id
     * @param orderId            订单id
     * @param userId             用户id
     * @param workingProceduceId 工序id
     * @param completedNumber    本次完成数量
     * @param problemNumber      本次问题数量
     * @return
     * @throws BizzException
     */
    @Override
    public boolean commitCheck(Long itemId, Long orderId, Long userId, Long workingProceduceId, int completedNumber, int problemNumber) throws BizzException {

        //判断这个人是不是这个部门的
        User user = iUserService.getById(userId);
        if (user == null) {
            throw new BizzException("员工不存在");
        }
        //查询这个工序属于哪个部门
        ItemWorkingprocedure workingprocedure = itemWorkingprocedureService.getById(workingProceduceId);
        if (user.getDeptId() != workingprocedure.getDept()) {
            throw new BizzException(user.getReallyName() + " 不属于 " + iDeptService.getById(workingprocedure.getDept()).getDeptName() + ",不允许提交!");
        }


        LambdaQueryWrapper<Plan> planQuery = new LambdaQueryWrapper<>();
        planQuery.eq(Plan::getPlanDate, DateUtils.getNowDate());
        planQuery.eq(Plan::getItemId, workingprocedure.getItemId());
        planQuery.eq(Plan::getOrderId, orderId);
        Plan one = iPlanService.getOne(planQuery);
        if (one == null) {
            throw new BizzException("今日无排班 不可提交!");
        }
        //报废率
        Integer scrapRate = iItemService.getById(itemId).getScrapRate();
        //今日生产数
        double todaySize = one.getWorkHours() * one.getHourlyCapacity() * ((100 + scrapRate) / 100d);
        if (completedNumber + problemNumber > todaySize) {
            throw new BizzException("完成数不能大于今日生产总数!");
        }

        //(非第一次)  本次提交数量 +  历史完成数量  <= 领取数量
        List<ItemWorkingprocedureResp> detail = itemWorkingprocedureService.detail(orderId, itemId, workingprocedure.getDept());
        int historySize = 0;
        for (ItemWorkingprocedureResp itemWorkingprocedureResp : detail) {
            if (itemWorkingprocedureResp.getId() == workingProceduceId) {
                for (ItemWorkingprocedureInfo info : itemWorkingprocedureResp.getInfos()) {
                    if (info.getUserId() == userId) {
                        historySize += (info.getCompleteNumber() + info.getProblemNumber());
                    }
                }
            }
        }

        //查询这个员工总领料数
        LambdaQueryWrapper<ItemWorkingprocedurePicking> pickingQuery = new LambdaQueryWrapper<>();
        pickingQuery.eq(ItemWorkingprocedurePicking::getItemId, itemId);
        pickingQuery.eq(ItemWorkingprocedurePicking::getOrderId, orderId);
        pickingQuery.eq(ItemWorkingprocedurePicking::getWorkingProcedureId, workingProceduceId);
        pickingQuery.eq(ItemWorkingprocedurePicking::getUserId, userId);
        List<ItemWorkingprocedurePicking> list = list(pickingQuery);
        if (list == null && list.size() == 0) {
            throw new BizzException("未领料 不可以提交完成!");
        }
        int pickingsize = 0;
        for (ItemWorkingprocedurePicking itemWorkingprocedurePicking : list) {
            pickingsize += itemWorkingprocedurePicking.getPickingSize();
        }
        if (historySize + completedNumber + problemNumber > pickingsize) {
            throw new BizzException("提交数量大于领料数量,请检查后提交!");
        }


        return true;
    }
}
